/**
 * <p>文件名:		JmxServer.java</p>
 * <p>版权:		CopyrightTag</p>
 * <p>公司:		千方集团CTFO</p>
 * @author		周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 */

package com.caits.lbs.framework.services.jmx;

import java.io.IOException;
import java.net.InetAddress;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;

import org.apache.log4j.Logger;

import com.caits.lbs.framework.Constants;
import com.caits.lbs.framework.log.CommonLogFactory;


/**
 * <p>
 * JmxServer
 * </p>
 * <p>
 * 用途：原生jmx服务实现类,需要在java启动参数中增加对应的jmx参数即可
 * </p>
 * 
 * @author 周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 * @version 0.0.1 2011-7-6
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-7-6 下午4:29:40</td>
 *          </tr>
 *          <tr>
 *          <td>0.0.1</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-7-6 下午4:29:40</td>
 *          <td>0.0.2</td>
 *          <td>修改类</td>
 *          <td>xxx</td>
 *          <td>x年x月x日</td>
 *          </tr>
 *          </table>
 */
public class JmxServer {

	private static JmxServer instance;
	/** 日志类 */
	private  Logger log = CommonLogFactory.getLog();
	
	/** 服务器实例 */
	private MBeanServer mbserver = null;
	
	/** 连接服务器 */
	private JMXConnectorServer connectorServer;

	/**
	 * 初始化 
	 */
	private void initialize() {
		if (this.mbserver != null && this.connectorServer != null
				&& this.connectorServer.isActive()) {
			return;
		}
		// 创建MBServer
		String hostName = null;
		try {
			InetAddress addr = InetAddress.getLocalHost();
			hostName = addr.getHostName();
		} catch (IOException e) {
			log.error("Get HostName Error", e);
			hostName = "localhost";
		}
		String host = System.getProperty("hostName", hostName);
		try {
			boolean enableJMX = Boolean.parseBoolean(System.getProperty(
					Constants.MANAGEMENT_JMX_ENABLE, "false"));
			if (enableJMX) {
				log.warn("开始获取本地JMX服务器.");
				//this.mbserver = ManagementFactory.getPlatformMBeanServer();
				// Retrieving MBean server   
				if (MBeanServerFactory.findMBeanServer(null).size() > 0) {   
					mbserver = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
					
				} else {   
					mbserver = MBeanServerFactory.createMBeanServer();
				}
				log.warn("已获取JMX服务器."+mbserver.getDefaultDomain());
				int port = Integer.parseInt(System.getProperty(Constants.MANAGEMENT_JMX_PORT, "9393"));
				log.warn("jmx server " +host+":"+ port);
			}
		} catch (Exception e) {
			log.error("create MBServer error", e);
		}
	}

	/**
	 * 获得单一实例 
	 * @return
	 */
	public static JmxServer getInstance() {
		if(instance==null){
			try{
				instance = new JmxServer();
				instance.initialize();
			}catch(Exception e){
				System.out.println("初始化JmxServer异常.msg="+e.getLocalizedMessage());
			}
		}
		return instance;
	}

	/**
	 * 是否注册某类型 
	 * @param name
	 * @return
	 */
	public boolean isRegistered(String name) {
		try {
			return this.mbserver != null
					&& this.mbserver.isRegistered(new ObjectName(name));
		} catch (Exception e) {
			log.error("server error",e);
			return false;
		}
	}

	/**
	 * 连接是否有效 
	 * @return
	 */
	public boolean isActive() {
		return this.mbserver != null && this.connectorServer != null
				&& this.connectorServer.isActive();
	}

	/**
	 * 获得管理类的数量 
	 * @return
	 */
	public int getMBeanCount() {
		if (this.mbserver != null) {
			return this.mbserver.getMBeanCount();
		} else {
			return 0;
		}
		
	}

	/**
		 * 注册一个对象 
		 * @param o
		 * @param name
		 */
		public void addObject(Object o) {
			String name=o.getClass().getPackage().getName() + ":type="
					+ o.getClass().getSimpleName()+o.hashCode();
			if (isRegistered(name)) {
				return;
			}
			// 注册MBean
			if (this.mbserver != null) {
				try {
					this.mbserver.registerMBean(o, new ObjectName(name));
				} catch (Exception e) {
					log.error("addObject MBean object error", e);
				}
			}
		}

	/**
	 * 关闭连接 
	 */
	public final void shutdown() {
		try {
			if (this.connectorServer != null && this.connectorServer.isActive()) {
				this.connectorServer.stop();
				log.warn("JMXConnector stop");
			}
		} catch (IOException e) {
			log.error("Shutdown Xmemcached MBean server error", e);
		}
	}
}
